/** \file translate.h
* A second visitor implementation of a ProgGraph
*/

#ifndef _TRANSLATE_H_
#define _TRANSLATE_H_

#include "graph.h"
#include "gminiGraph.h"
#include "DecoratedNodeType.h"
#include "translatorHelper.h"
#include "visitor.h"


//TODO: be careful to delete DecoratedNodeType pointers after graph is deleted

class TranslateVisitor: public Visitor
{
private:
	ForwardGraphTranslator * translator;
	
public:
	TranslateVisitor(GminiGraph * our_graph)
	{
		translator= new ForwardGraphTranslator(our_graph);
	}
	virtual void initialize() {}
	virtual void visitEdge(Edge * e)
	{
		translator->translateAndInsert(e);
	}
	virtual void visitNode(Node * n)
	{
		translator->translateAndInsert(n);
	}
	NewGraph * getTranslatedGraph()
	{
		return translator->getTranslatedGraph();
	}
	virtual void finish() {}
	~TranslateVisitor()
	{
		delete translator;
	}
};


/**
* \class TranslateVisitor2
* \author Layale Constantine & Jad Makhlouta
* \brief a visitor class that will map the nodes and edges of ProgGraph into nodes and edges for a new g-mini Graph
*
*/
class TranslateVisitor2
{
private:
	BackwardGraphTranslator * translator;//<! helper class to perform the mapping from ProgGraph to g-mini Graph

public:
	TranslateVisitor2(NewGraph & new_graph)
	{
	NewGraph * g = &new_graph;
	translator= new BackwardGraphTranslator(g);
	}

	bool operator ()(NewGraph::ProgEdge * edge)
	{
		translator->translateAndInsert(edge);
		return true;
	}
	bool operator()(NewGraph::ProgNode * node)
	{
	translator->translateAndInsert(node);
		return true;
	}
	GminiGraph * getTranslatedGraph()
	{
		return translator->getTranslatedGraph();
	}
	~TranslateVisitor2()
	{
		delete translator;
	}
};

typedef NewGraph::DFTraverse<TranslateVisitor2> DFTraverseTranslate;

/*
*\brief calls DFTraverse on a ProgGraph with TranslateVisitor2 as the visitor class in order to map the current graph into a
* g-mini graph
*
*\returns a mapped version of ProgGraph into g-mini Graph
*/
GminiGraph * translate( NewGraph & new_graph)
{
	TranslateVisitor2 v(new_graph);
	DFTraverseTranslate t(v,1);
	t(new_graph);
	new_graph.resetColor();
	return v.getTranslatedGraph();
}

NewGraph * translate( GminiGraph * our_graph)
{
	TranslateVisitor v(our_graph);
	Traversal t(*our_graph,v);
	t();
	return v.getTranslatedGraph();
}

#endif
